package thread;

import java.util.concurrent.locks.ReentrantLock;

/**
 * @author zxl
 * @version 1.0
 * @date 2021/10/26 21:20
 * Lock
 * lock为显示锁（手动开启和关闭） 只有代码块锁    性能更好，易扩展
 * synchronized为隐式锁        有方法锁和代码块锁
 */

public class ThreadLock {
    public static void main(String[] args) {
        /*不加锁会出现多个线程拿同一个值*/
        ThreadLockTest threadLockTest = new ThreadLockTest();
        new Thread(threadLockTest).start();
        new Thread(threadLockTest).start();
        new Thread(threadLockTest).start();
    }

}
class ThreadLockTest implements Runnable{

    private int num = 100;
    /**
     * 可重入锁：可重入就是说‘某个线程’已经获得某个锁，可以再次获取锁而不会出现死锁 （并不是两个线程枪同一个锁）
     *     例如一个获得了user对象并加了锁，可以再次或的User对象的这把锁，而不会出现死锁
     *     可重入，就是可以重复获取相同的锁，synchronized和ReentrantLock都是可重入的
     *     可重入降低了编程复杂性
     */
    private final ReentrantLock lock = new ReentrantLock();

    @Override
    public void run() {
        while (true){
            lock.lock();  //加锁
            try{
                if(num>0){
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "拿到了"+num--);
                }else {
                    break;
                }
            }finally {
                lock.unlock();  //解锁
            }
        }
    }
}
